<?php

namespace App\Services\Draw\PoolGroupObject;


use App\Exceptions\BasicException;
use App\Repositories\GiftRepository;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

/**
 * 许愿魔法书抽奖实体
 * @author wrh
 */
class FantasyIndependentPoolGroup extends PoolGroup
{
    public $group_ids;
    public $independent_id;
    public $poolIndependentModel;
    public $remain_group_count;


    public function getNewPoolGroup()
    {
        //group变更时更新数据 需要加锁
        $groupIds = explode(',', $this->group_ids);
        if (empty($groupIds)) {
            throw new BasicException(-1, "模板未配置");
        }
        if ($this->remain_group_count > 0) {
            $this->poolIndependentModel->one(['id' => $this->independent_id], true);
            $groupKey       = count($groupIds) - $this->remain_group_count;
            $this->group_id = $groupIds[$groupKey];
        }
        return $this;
    }

    public function createNextRoundPrizes(Collection $templatePrizes, $user, int $drawCount)
    {
        // 清空本轮礼物总数
        $this->poolPrizeModel->updateData(['independent_id' => $this->independent_id, 'group_id' => $this->group_id], ['template_count' => 0]);
        $this->poolPrizeModel->appendPrizes($this, $templatePrizes, $user);
    }

//    public function updateExtraData()
//    {
//        $this->poolIndependentModel->updateData(['id' => $this->independent_id], ['group_id' => $this->group_id]);
//        //$this->independent_id
//    }


    public function updatePoolDrawData(array $drawIOPut, int $poolIncrRound, int $drawCount)
    {
        $poolUpdateData = $this->updateNormalPoolDrawData($this, $drawIOPut, $poolIncrRound, $drawCount);

        $input  = $drawIOPut['input'];
        $output = $drawIOPut['output'];
        //独立池子投入产出更新
        $independentUpdateData['input']  = DB::raw('input +' . $input);
        $independentUpdateData['output'] = DB::raw('output +' . $output);
        if ($this->group_id != $this->current_group_id) {
            //切换组合的时候清空当前投入产出
            $independentUpdateData['group_id']           = $this->group_id;
            $independentUpdateData['remain_group_count'] = DB::raw('remain_group_count -1');
            if ($this->current_group_id == 0) {
                $independentUpdateData['input_pre']  = DB::raw('input_pre +' . $input);
                $independentUpdateData['output_pre'] = DB::raw('output_pre +' . $output);
            } else {
                $independentUpdateData['input_pre']  = $input;
                $independentUpdateData['output_pre'] = $output;
            }
        } else {
            $independentUpdateData['input_pre']  = DB::raw('input_pre +' . $input);
            $independentUpdateData['output_pre'] = DB::raw('output_pre +' . $output);
        }

        $this->poolIndependentModel->updateData(["id" => $this->independent_id], $independentUpdateData);

        return $poolUpdateData;
    }

    public function getPoolPrizeList($user)
    {
        //先通过group查询prize表获取 礼物模板ID  再通过模板ID查询礼物
        $poolPrizeList = $this->poolPrizeModel->getPrizeListWithGift(['user_id' => $user->user_id], ['independent_id', 'gift_template_id', 'count',
            'group_id', 'template_count', 'gift_id']);
        $giftIds       = $poolPrizeList->pluck('gift_id');
        $gifts         = (new GiftRepository())->giftsByIdsWithField($giftIds, ['id', 'price']); // 抽中礼物信息
        $giftsWithId   = $gifts->keyBy('id');
        foreach ($poolPrizeList as &$template) {
            $template['price'] = $giftsWithId[$template['gift_id']]['price'];
        }
        return $poolPrizeList;
    }

    public function decPoolPrize(array $drawPrizes)
    {
        return $this->poolPrizeModel->batchDecPrizesByGroup($this, $drawPrizes);
    }

    public function getDrawPrizesCount(array $drawPrizes)
    {
        $drawPrizesCount = 0;
        foreach ($drawPrizes as $independentPrize) {
            foreach ($independentPrize as $groupPrize) {
                foreach ($groupPrize as $prizeCount) {
                    $drawPrizesCount += $prizeCount;
                }
            }
        }
        return $drawPrizesCount;
    }

    public function transformDrawPrizes(array $drawPrizes){
        $templateDrawPrizes = [];
        foreach ($drawPrizes as $independentPrize) {
            foreach ($independentPrize as $groupId => $groupPrize) {
                foreach ($groupPrize as $templateId => $prizeCount) {
                    if (isset($templateDrawPrizes[$groupId][$templateId])) {
                        $templateDrawPrizes[$groupId][$templateId] += $prizeCount;
                    } else {
                        $templateDrawPrizes[$groupId][$templateId] = $prizeCount;
                    }
                }
            }
        }
        return $templateDrawPrizes;
    }

    /**
     * 检查本期礼物是否充足
     * @param Collection $poolPrizeList
     * @param int $drawCount
     * @param $user
     * @param Collection $poolConfig
     * @return bool
     */
    public function checkDrawRoundPrizeCount(Collection $poolPrizeList, int $drawCount, $user, $poolConfig)
    {
        if ($poolPrizeList->isEmpty()) {
            return false;
        }
        $smallPrizeCount = $poolPrizeList->where('count', '>', 0)->sum('count');
        if ($drawCount > $smallPrizeCount) { // 奖池的剩余礼物不足抽取次数
            return false;
        }

        return true;
    }


    // 追加奖励
    public function appendPrizes(array $prizes, array $append)
    {
        foreach ($append as $independentId => $independentPrize) {
            foreach ($independentPrize as $groupId => $groupPrize) {
                foreach ($groupPrize as $prizeId => $prizeCount) {
                    if (isset($prizes[$independentId][$groupId][$prizeId])) {
                        $prizes[$independentId][$groupId][$prizeId] += $prizeCount;
                    } else {
                        $prizes[$independentId][$groupId][$prizeId] = $prizeCount;
                    }
                }
            }
        }

        return $prizes;
    }


    public function drawPrizes(Collection $poolPrizeList, $poolConfig, $poolGroup, $user, $drawCount)
    {
        $remainDrawCount = $drawCount;

        $drawPrizes = [];
        if ($drawCount <= 0) {
            return [];
        }
        $poolCount = $poolPrizeList->where('count', '>', 0)->sum('count');

        //奖池礼物不足则全部抽取
        if ($poolCount < $drawCount) {
            //todo 是否要添加补充逻辑
            throw new BasicException(-1, '奖池礼物不充足');
        }

        return $this->drawNormalPrize($poolPrizeList, $remainDrawCount, $poolConfig);
    }


    public function drawNormalPrize(Collection $poolPrizeList, int $count, $poolConfig)
    {

        $normalPool = $poolPrizeList
            ->where('count', '>', 0);
        $sumCount   = $normalPool->sum('count');
        $normalPool = $normalPool->toArray();
        if ($sumCount < 1) {
            return [];
        }

        //根据剩余数量进行权重抽取
        $prizeId = 0;
        $groupId = 0;
        $independentId = 0;
        //权重总值
        $totalWeight = $sumCount;
        $randomId    = mt_rand(1, $totalWeight);
        $weight      = 0;
        $drawPrizes  = [];
        while ($count) {
            foreach ($normalPool as &$mPool) {
                if ($randomId > $weight && $randomId <= ($mPool['count'] + $weight)) {
                    $independentId = $mPool['independent_id'] ?? $this->independent_id;
                    $prizeId = $mPool['gift_template_id'];
                    $groupId = $mPool['group_id'];
                    $mPool['count']--;
                    $totalWeight--;
                    $weight = 0;
                    break;
                } else {
                    $weight += $mPool['count'];
                }
            }
            if ($totalWeight > 0) {
                $randomId = mt_rand(1, $totalWeight);
            }

            if (isset($drawPrizes[$independentId][$groupId][$prizeId])) {
                $drawPrizes[$independentId][$groupId][$prizeId]++;
            } else {
                $drawPrizes[$independentId][$groupId][$prizeId] = 1;
            }
            $count--;
        }

        return $drawPrizes;

    }
//    public function getPoolPrizeList()
//    {
//        //先通过group查询prize表获取 礼物模板ID  再通过模板ID查询礼物
//        $poolPrizeList = $this->prizeModel->getPrizeListWithGift(['pool_id' => $this->pool_id], ['gift_template_id', 'count',
//            'group_id', 'template_count', 'gift_id']);
//        $giftIds       = $poolPrizeList->pluck('gift_id');
//        $gifts         = (new GiftRepository())->giftsByIdsWithField($giftIds, ['id', 'price']); // 抽中礼物信息
//        $giftsWithId   = $gifts->keyBy('id');
//        foreach ($poolPrizeList as &$template) {
//            $template['price'] = $giftsWithId[$template['gift_id']]['price'];
//        }
//        return $poolPrizeList;
//    }
}
